package com.itheima.health.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.itheima.health.mapper.OrderMapper;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.service.MemberService;
import com.itheima.health.service.OrderService;
import com.itheima.health.service.OrderSettingService;
import com.itheima.health.utils.date.DateUtils;
import com.itheima.health.utils.redis.RedisUtil;
import com.itheima.health.utils.resources.RedisMessageConstant;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Reference
    private OrderSettingService orderSettingService;

    @Reference
    private MemberService memberService;

    /**
     *  订单生成业务实现
     * @param map
     * @return
     */
    @Override
    @LcnTransaction  //    事务发起者  起始方法上添加该注解
    public Order add(Map map) {
        //  1.  校验验证码    错误  过期  没有写
        String  telephone = (String)map.get("telephone");
        String  codeFromMap = (String)map.get("validateCode");
        String  codeFromRedis = RedisUtil.get(RedisMessageConstant.SENDTYPE_ORDER+telephone);
        String orderdate = (String)map.get("orderDate");
        String setmealId = (String)map.get("setmealId");

        Order order = null;

        if(StringUtils.isBlank(codeFromMap)){
            throw  new RuntimeException("验证码必填！");
        }
        if(StringUtils.isBlank(codeFromRedis)){
            throw  new RuntimeException("验证码过期，请重新发送！");
        }

        if(!codeFromRedis.equals(codeFromMap)){
            throw  new RuntimeException("验证码错误，请重新输入！");
        }
        //  2  是否当天可以预约
        int count = orderSettingService.isOrderOkByOrderDate(orderdate);
       if(count<=0){
           throw  new RuntimeException("预约已满，请择日再约！");
       }
       // 3.   判断用户是否重复预约  调用会员服务  当前 订单服务！
        Member member = memberService.findMemberByTelephone(telephone);
       if(member!=null){
           //  老会员  重复下单 可能
             int isCount = baseMapper.isGenerateOrderOrNot(member.getId(),Integer.parseInt(setmealId),orderdate);
             if(isCount>0){
                 throw  new RuntimeException("您已经预约过，请勿重复预约！");
             }
             //  老会员也可以下单
           order =    addOrder(map,member.getId()); //  订单表 添加记录  +  t_orderseting  已经预约数+1
       }else{
           // 新会员   下单。。。
           member = new Member();
           member.setName((String)map.get("name"));
           member.setIdCard((String)map.get("idCard"));
           member.setPhoneNumber(telephone);
           member.setRegTime(new Date(System.currentTimeMillis()));
           member.setSex((String)map.get("sex"));
           int mid =  memberService.saveMember(member) ;  //  会员表录入记录
//           System.out.println(1/0);  //  模拟系统代码异常
//           System.out.println(1/0);  //  模拟系统代码异常
           order =    addOrder(map,mid);
       }

        return order;
    }

    @Override
    public Map findOrderInfoByOrderId(int oid) {
        return baseMapper.findOrderInfoByOrderId(oid);
    }

    /**
     *    订单添加  +  预约表  +1 更新已经预约数据
     * @param map
     * @param id
     * @return
     */
    @LcnTransaction
    private Order addOrder(Map map, Integer mid) {
        String orderdate = (String)map.get("orderDate");
        String setmealId = (String)map.get("setmealId");
            Order  order = new Order();
            order.setMemberId(mid);
            order.setSetmealId(Integer.parseInt(setmealId));
            order.setOrderDate(DateUtils.parseString2Date(orderdate,"yyyy-MM-dd"));
            order.setOrderStatus("未到诊");
            order.setOrderType((String)map.get("orderType"));
            baseMapper.insert(order); // 插入数据库
            orderSettingService.updateReservationsByOrderDate(orderdate);
        return  order;
    }
}
